Repository navigation
docs(skills): a suite composes under manifest preserve; a flat composition of two apps under one package is refused - #33475
Conversation
…ition of two apps is refused
bootstrap.md's Multi-App Composition section said no app in this repo
uses composeStacks and named no strategy for a suite. It now teaches
composeStacks(stacks, { manifest: 'preserve' }) for a suite, points at
examples/app-multi-package, and states the STACK_SINGLE_APP_VIOLATION
(422) refusal of a flat composition. objectstack-ui SKILL.md App
Navigation names the same remedy. Both files pay in-file by deleting
restatements.
Claude-Session: https://claude.ai/code/session_01FEkQ5mo8ZsDz2BHVZiwWLs
Co-Authored-By: Claude <noreply@anthropic.com>
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: Read on ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
No must-fix, no should-fix. One nit, accepted. The ADR-0019 relay onto #33135 is the seat's (③), not this diff's. Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-14T22:27Z · isolated sub-agent at CONTRACT_REVIEW_TIER · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb 维护者速读
席位核对Verdict: ACCEPT, held for the maintainer · head
|
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: At-tier re-review of this head. The earlier record 6885186638 is not used as evidence; ③ says which of its findings stand. Read for this record: card #32977 with every comment, the PR body and file list, the net diff against ① Derived judgments
② Semver level
③ Boundary flags
④ Design judgment
The card carries no eval prompt and asks for none; the scenario judged against is the card's own (an agent composing a suite). No must-fix, no should-fix. Two nits, neither needing a head move. Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-15T00:31Z · isolated sub-agent at CONTRACT_REVIEW_TIER (served model verified by the seat) · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Correction: contract-review tierThe contract-review record(s) 6885186638 on this PR say The seat re-runs the review at |
Requested by Leehom · project thread
Fixes #32977
domain:skills#1 · os-project-manager · session_01FEkQ5mo8ZsDz2BHVZiwWLs
Clause-②: no
Metadata-protocol: none
维护者速读
bootstrap.md「多应用组合」一节改为:套件(一个 app 包加若干 module 包,各带一个应用)用composeStacks(stacks, { manifest: 'preserve' })组合,保留每个包自己的 id(examples/app-multi-package就这么用);扁平组合('last'默认、'first'、索引)只留一个 manifest,一个 app/module 包 id 下落两个以上应用即被拒(STACK_SINGLE_APP_VIOLATION,422)。删掉「本仓没有应用用它」这句错话。objectstack-ui/SKILL.md「App Navigation」补同一条补救:套件用preserve组合,扁平组合会被拒。composeStacks拒绝扁平组合出「一个包 id 下多个应用」,技能文字没教preserve,AI 照写扁平组合会白跑一轮被拒。@objectstack/skillspatch changeset;新增文字由同文件删除重复内容付账,两个文件都仍在 token 上限内,未抬任何上限;回滚即还原本 PR。skills/objectstack-platform/references/bootstrap.md的 Multi-App Composition 一节;skills/objectstack-ui/SKILL.md第 139–147 行(App Navigation 第二段)。node scripts/check-skills-token-ratchet.mjs | grep -E "bootstrap|objectstack-ui/SKILL",预期 bootstrap.md 1340/1343、objectstack-ui SKILL.md 3809/3814,均不超限。skills/**):请批准或合并。What changes
skills/objectstack-platform/references/bootstrap.md, § Multi-App Composition. ThecomposeStacks()paragraph said "No app in this repo uses it — read the schema before reaching for it" and named no strategy for a suite. It now says: a suite (an app package plus module packages, one app each) composes withcomposeStacks(stacks, { manifest: 'preserve' }), which keeps each package's own id (examples/app-multi-package); a flatmanifest('last', the default,'first'or an index) keeps one, so two or more apps under oneappormodulepackage id are refused (STACK_SINGLE_APP_VIOLATION, 422). Card Work items 1 and 2.skills/objectstack-ui/SKILL.md, § App Navigation (fold 6846119916 row 1). The suite sentence now ends with the remedy: the suite composes withcomposeStacks(stacks, { manifest: 'preserve' }), which serves each app under its own package id; a flat composition puts them under one and is refused..changeset/32977-skills-suite-composes-under-preserve.md:'@objectstack/skills': patch, carrying both declaration lines.docs/adr/0019-app-as-consumer-unit.mdis not touched (fold 6846119916 row 2). The folded row and docs: ADR-0019's enforcement log still lists a hand-built packages[] body as not judged, after #33074 and #33122 #33135 name the same sentence of the 2026-11-12 "Enforced for modules" note ("Two shapes are not judged ... a flatcomposeStacks... and a hand-builtpackages[]body"), so the ADR stays with docs: ADR-0019's enforcement log still lists a hand-built packages[] body as not judged, after #33074 and #33122 #33135 as the order rules. docs: ADR-0019's enforcement log still lists a hand-built packages[] body as not judged, after #33074 and #33122 #33135's Expected names only the hand-built body; the flat-composition half of that sentence is false too since PR feat(spec)!: composeStacks refuses a flat composition that puts two or more apps under one app or module package id, and every packages[] body is held to one app #32898, so docs: ADR-0019's enforcement log still lists a hand-built packages[] body as not judged, after #33074 and #33122 #33135's PR should rewrite the whole sentence (noted in the report for the seat).Paid in the same file (no ceiling moved)
bootstrap.md: the title's "(moved verbatim from SKILL.md)" (no longer true once this section changes); "this is how real multi-app composition happens" and "equal the physical table name" (the second restatesobjectstack-platform/SKILL.md§ Object naming); "Use barrel exports to keep config clean:" and "A minimal but complete project from scratch:" (each restates its heading); "(traditional)" and "(key becomes name) ... for readability" in the Map Format comments (the sentence above the block says the key becomes thename); thestack.zod.tsfile pointer (references/_index.mdcarries the schema pointers).objectstack-ui/SKILL.md: thesubformsexample's "relationshipField + columns are derived from the child object" comment (the paragraph under the list says the FK and columns are derived in every case); therequiresObject/requiresServicenote shortened to what it says ("hide an item whose optional system object or kernel service is missing"). The pinned lines named in the file's CEILINGS entry are untouched.Why
Read on
origin/main34c0522,packages/spec/src/stack.zod.ts:SINGLE_APP_PACKAGE_TYPES=app,module.SINGLE_APP_COMPOSE_REMEDYis the text every single-app finding names: "compose the packages into one artifact with composeStacks(stacks, { manifest: 'preserve' }), which keeps each package's own id (a flat composition puts every app back under one)".composeStackscallscollectComposedSingleAppErrors(stacks, composed, opts.manifest)and throwsStackSingleAppViolationError(code = 'STACK_SINGLE_APP_VIOLATION',status = 422fromStackRefusalError) with the headercomposeStacks single-app validation failed (N issues):. With nopackages[]in the result,flatSingleAppFindingrefuses when the composed manifest's type is in the set and the composedappshas more than one entry, naming each app with the input it came from.examples/app-multi-package/objectstack.config.tsline 68:export default composeStacks([ordersStack, coreStack], { manifest: 'preserve' });, so the old "No app in this repo uses it" was false.Acceptance notes
resolveArtifactCollections(@objectstack/runtime, named in 6846119916 as the platform reader the remedy could name) is not taught: the ask is thepreserveremedy, the file has no headroom, and an author composes withcomposeStacks, not with the runtime reader.origin/mainmoved to b5f2f51 (docs(skills): a vetted overlap-check hook template for insert and update #33292) after the branch was cut; it touches none of these files, so no merge.Verification
Head
f4fc5ea9, baseorigin/main34c0522.Line and token budget (skills/**)
skills/objectstack-platform/references/bootstrap.md: 190 to 188 lines, 5398 to 5390 bytes; token ratchet 1342 to 1340 (ceiling 1343, headroom 3).skills/objectstack-ui/SKILL.md: 301 to 301 lines, 15276 to 15253 bytes; token ratchet 3814 to 3809 (ceiling 3814, headroom 5).skills/*/SKILL.md: 4602 to 4602 lines. Bundle total (whole shipped tree): 244649 to 244642 tokens.node scripts/pm/check-skill-line-ratchet.mjs: exit 0.node scripts/check-skills-token-ratchet.mjs: exit 0. No ceiling raised.Derived gates: 48 derived, 46 run green, 2 NOT MEASURED
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 48 families for the three paths.turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --filter=@objectstack/specran first under the verify lock (VERDICT command-exit 0, 87s). Each family was then run with its exit code captured before any pipe.check-adr-0087-registration,check-empty-changeset,check-skills-token-ratchet(scan and--self-testeach),@objectstack/lint check:doc-formula-expressions,@objectstack/spec check:skill-docsandcheck:skill-refs,check:doc-authoring,check:nul-bytes,check:pm-governed-merges,check:published-files,check:scaffold-emission-policy,check:skill-compatibility,check:skill-frame-sync,check:skill-identifier-liveness,check:skill-links;check:dts-closureandcheck:sourcemap-no-sources-contentover the 5 built packages only.dist/):check:dual-build-cjs-loads,check:lean-entry-closure. No package source is touched, so no full build was paid; CI builds and runs them.--ran: "48 derived famil(ies) accounted for — 46 run, 2 NOT-MEASURED (2 DERIVED from a recorded exit 3)".Tier and governed readings
dispatch-gates --tier: MANDATORY contract-review tier,skills/**under clause ① (the published catalog); no one-line exit for this surface.node scripts/pm/check-governed-merges.mjs --branch claude/project-thread-rqofat: exit 3, GOVERNED, landing tier H. 2 of 3 paths on the register (skills/**); the changeset is not. Size +32 / -24, under the 3000 threshold.🤖 Generated with Claude Code
https://claude.ai/code/session_01FEkQ5mo8ZsDz2BHVZiwWLs